
/**
 * 伤害计算
 * @param {Object{data, rate, rea}} any 
 * @returns {Object{qw, bj}} 
 * getDmg({data, rate:2.1}) => {qw , bj}
 */
function getDmg({data, rate=1, rea}){
    let {criticalRate,criticalStrike,dmgRate,base,attRate,fixedAtt} = data
    if(criticalRate > 100){criticalRate = 100}
    if(criticalRate < 0) { criticalRate = 0 }
    let baseatQ = ((base * (1 + (attRate||0) / 100) + fixedAtt) * rate);
    let dmgQ = 1 + (dmgRate / 100);
    
  
    let crStrikeQ = 1 + (criticalStrike / 100);
    let crQWQ = (1-(criticalRate/100) + (1 + (criticalStrike/100)) * (criticalRate/100)) 
    let reaQ = 1;
    if(rea){
        let {reaction, reactionQ, reactionDmgAdd} = rea
        reaQ = (1 + reactionDmgAdd + (278*reaction/(reaction+1400)) / 100) * reactionQ;
    }


    let baseQ = baseatQ + (data.dmgZhi||0);
    

    return {
        qw: baseQ * crQWQ  * dmgQ * reaQ,
        bj: baseQ * crStrikeQ * dmgQ * reaQ
    }
}

/**
 * 抗性减伤系数
 * @param {Number} 抗性 
 * @returns {Number} 系数
 * reduceResistanceK(10)  =>  0.9
 */
function reduceResistanceK (resistance) {
    if(resistance < 0) {
        return 1 - resistance/200
    } else if (resistance >=0 && resistance < 75){
        return 1 - resistance/100
    } else {
        return 1/(1+resistance/100*4)
    }
}

/**
 * 等级压制减伤系数
 * @param {Number, Number, Number} 你的等级  敌人的等级  减防 
 * @returns {Number} 系数
 * lvSuppressK(90, 100, 23)  =>  0.5523255813953488
 */
function lvSuppressK(youLv=0, eLv=0, td){
    return (100+youLv)/(100+youLv+(100+eLv)*(td? (100-td)/100 : 1))
}


/**
 * 对象数值增加 返回新对象
 * @param {Array} 
 * @returns {Object} 
 * objValueAdd([obj])  =>  obj
 */
function objValueAdd(ObjArr) {
    let ret = {}
    ObjArr.forEach(obj => {
        for (let key in obj) {
            if(!ret.hasOwnProperty(key)) {
                ret[key] = obj[key]
            } else if(/^\d+\.?\d*$/.test(obj[key])) {
                ret[key] += obj[key]
            }
        }
    })
    return ret
}



module.exports = {
    getDmg,reduceResistanceK,lvSuppressK,objValueAdd
}



/*

    原神伤害计算公式

	(伤害值) x (双爆) x (增伤) x (反应) x (抗性) x (防御)  

	伤害值： (攻击力 x 技能倍率) x 伤害值提升系数 + 伤害固定值
             伤害值提升系数为某些角色的特殊效果 目前只有宵宫的e 和 行秋的4命
             伤害固定值例如某些角色根据生命的xx%加伤害值  云堇的大招给别人普攻附加伤害值 申鹤冰羽给冰伤附加伤害值
             
	双爆：   数学期望算法为:   1-暴击 + 暴击x(1+爆伤)  比如80/160 =  1-0.8 + 0.8x(1+1.6) = 2.28  ps:暴击率超过100时算100
             
    增伤:    各种增伤相加 元素伤害 莫娜增伤 普攻重击增伤等等加算

	增幅反应:  蒸发融化系数 x 反应增伤    系数:火打水蒸发1.5  水打火蒸发2  火打冰融化2 冰打火融化1.5  
             反应增伤部分是 精通转化的增伤和其他反应增伤相加(比如魔女四件套 莫娜1命) 
             精通转化的反应增伤只有经验公式为 (278*精通/(精通+1400)) / 100) 比如80精通 = 15%  160->28.5% 200->34.75%

	抗性:    0~75抗性时候 直接-百分比伤害  比如10抗性 就等于总伤害*0.9   
			 75抗性以上 1/(1+抗性/100*4) 比如100抗性就是总伤害*0.2
			 0以下抗性  相当于- 抗性/2 的伤害  比如抗性-20  总伤害-(-20/2)% = 总伤害+10% =  总伤害*1.1
             概括: 0以上抗性 减抗收益极高   0以下抗性 减抗收益减半

	防御:    (100+你的等级)/(100+你的等级+(100+敌人等级)*((100-减防)/100)
			 比如没有减防时 双方等级为90      (100+90)/(100+90+(100+90)*((100-0)/100)) = 0.5
			 减防御为60时   (100+90)/(100+90+(100+90)*((100-60)/100)) = 0.7142857142857143
			 减防为100时    (100+90)/(100+90+(100+90)*((100-100)/100)) = 1
             概括: 减防的收益是递增的 当减防超过50% 其收益将超过50%减抗 目前也就雷神2命和神子满命有超高的减防效果
             其他角色的减防太低 

*/